MapGen = class('MapGen')

function MapGen:initialize( name, deck, prevMap, width, height, floor_type, wall_type, space_type)
	self.name = name
	self.deck = deck
	self.prevMap = prevMap
	self.width = width or 32
	self.height = height or 32
	self.floor_type = floor_type or floor_tile
	self.wall_type = wall_type or wall_tile
	self.space_type = space_type or space_tile
	self.layout = {}
	self.map_x = 0
	self.map_y = 0
	self.visited = false
	self.features = {}
	self.items = {}
	self.scourge = {}
	self.enemies = {}
end

function MapGen:get_map()
	local m = {}
	self:insert_map(m)
	m.name = self.name
	m.floor_type = self.floor_type
	m.deck = self.deck
	m.map_x = self.map_x
	m.map_y = self.map_y
	m.id = self.id
	m.layout = self.layout
	m.features = self.features
	m.items = self.items
	m.scourge = self.scourge
	m.enemies = self.enemies

	return m
end

function MapGen:gen( reps, reps2 )

	local reps = reps or 5
	local reps2 = reps2 or 3

	for y = 1, self.height do
		self.layout[y] = {}
		for x = 1, self.width do

			local r = RNG:random(100)

			if r < 45 then
				self.layout[y][x] = self.wall_type
			else
				self.layout[y][x] = self.floor_type
			end

		end
	end

	for i = 1, reps do
		for y = 1, #self.layout do
			for x = 1, #self.layout[y] do

				local z = self:surrounding_walls(x, y, 1, 1)
				local q = self:surrounding_walls(x, y, 2, 2)

				if z > 5 then self.layout[y][x] = self.wall_type end
				if q < 2 then self.layout[y][x] = self.wall_type end

			end
		end
	end

	for i = 1, reps2 do
		for y = 1, self.height do
			for x = 1, self.width do
				local z = self:surrounding_walls(x, y, 1, 1)
				local q = self:surrounding_walls(x, y, 2, 2)

				if z > 5 then self.layout[y][x] = self.wall_type end

				self:surrounding_diagonals(x, y)

			end
		end
	end

	for y = 1, self.height do
		for x = 1, self.width do
			if y == 1 or x == 1 or
				y == self.height or x == self.width then
				self.layout[y][x] = self.space_type
			end

			if y == 2 or x == 2 or
				y == self.height-1 or x == self.width-1 then

				if self.layout[y][x] ~= self.space_type then
					self.layout[y][x] = self.wall_type
				end

				if y == 2 then
					if self.layout[y+1][x] == self.space_type then
						self.layout[y][x] = self.space_type
					end
				end

				if x == 2 then
					if self.layout[y][x+1] == self.space_type then
						self.layout[y][x] = self.space_type
					end
				end

				if y == self.height-1 then
					-- this is y+1 in moai, might be a bug but not sure
					if self.layout[y-1][x] == self.space_type then
						self.layout[y][x] = self.space_type
					end
				end

				if x == self.width-1 then
					if self.layout[y][x-1] == self.space_type then
						self.layout[y][x] = self.space_type
					end
				end
			end

		end
	end

	return self.layout
end

function MapGen:insert_map(m)

	self.id = #map+1
	map[self.id] = m

end


function MapGen:surrounding_walls(x, y, distX, distY)

	local distX = distX or 1
	local distY = distY or 1
	local walls = 0


	if distX == 1 and distY == 1 then
		if self.layout[y][x] then
			if self.layout[y-1] then
				if self.layout[y-1][x] then
					if self.layout[y-1][x] == self.wall_type then walls = walls+1 end
				end
				if self.layout[y-1][x+1] then
					if self.layout[y-1][x+1] == self.wall_type then walls = walls+1 end
				end
				if self.layout[y-1][x-1] then
					if self.layout[y-1][x-1] == self.wall_type then walls = walls+1 end
				end
			end
			if self.layout[y][x+1] then
				if self.layout[y][x+1] == self.wall_type then walls = walls+1 end
			end
			if self.layout[y][x-1] then
				if self.layout[y][x-1] == self.wall_type then walls = walls+1 end
			end
			if self.layout[y+1] then
				if self.layout[y+1][x] then
					if self.layout[y+1][x] == self.wall_type then walls = walls+1 end
				end
				if self.layout[y+1][x+1] then
					if self.layout[y+1][x+1] == self.wall_type then walls = walls+1 end
				end
				if self.layout[y+1][x-1] then
					if self.layout[y+1][x-1] == self.wall_type then walls = walls+1 end
				end
			end


		end
	else
		for y1 = 1, distY do
			for x1 = 1, distX do
				local tile, tile2
				if self.layout[y+y1-1] then
					if self.layout[y+y1-1][x+x1-1] then
						tile = self.layout[y+y1-1][x+x1-1]
					end
				end
				if self.layout[y-y1] then
					if self.layout[y-y1][x-x1] then
						tile2 = self.layout[y-y1][x-x1]
					end
				end

				if tile == self.wall_type then walls = walls+1 end
				if tile2 == self.wall_type then walls = walls+1 end
			end
		end
	end

	return walls

end

function MapGen:surrounding_diagonals(x, y)

	if self.layout[y][x] == self.wall_type then

		local ul, ur, u, bl, br, b, l, r
			if self.layout[y-1] then
				if self.layout[y-1][x-1] then
					ul = self.layout[y-1][x-1]
				end
				if self.layout[y-1][x+1] then
					ur = self.layout[y-1][x+1]
				end
				if self.layout[y-1][x] then
					u = self.layout[y-1][x]
				end
			end
			if self.layout[y+1] then
				if self.layout[y+1][x-1] then
					bl = self.layout[y+1][x-1]
				end
				if self.layout[y+1][x+1] then
					br = self.layout[y+1][x+1]
				end
				if self.layout[y+1][x] then
					b = self.layout[y+1][x]
				end
			end

			if self.layout[y][x-1] then
				l = self.layout[y][x-1]
			end
			if self.layout[y][x+1] then
				r = self.layout[y][x+1]
			end



			if l == self.floor_type and
				u == self.floor_type and
				r == self.floor_type then
				self.layout[y][x] = self.floor_type
			end
			-- b was lo, think it was a bug
			if l == self.floor_type and
				b == self.floor_type and
				r == self.floor_type then
				self.layout[y][x] = self.floor_type
			end

			if (ul == self.wall_type or ul == self.space_type ) and
				(ur == self.wall_type or ur == self.space_type) and
				(bl == self.wall_type or bl == self.space_type) and
				(br == self.wall_type or br == self.space_type) and
				(l == self.wall_type or l == self.space_type) and
				(r == self.wall_type or r == self.space_type) and
				(u == self.wall_type or u == self.space_type) and
				(b == self.wall_type or b == self.space_type) then
				self.layout[y][x] = self.space_type
			end


	end

end

function MapGen:get_floors()
	local floors = {}
	for y = 1, self.height do
		for x = 1, self.width do
			if self.layout[y][x] == self.floor_type then
				local f = #floors+1
				floors[f] = {}
				floors[f].x = x
				floors[f].y = y
			end
		end
	end
	return floors
end

function MapGen:gen_features()
	local floors = self:get_floors()
	local r = RNG:random(#floors)

	self.features.start = {}
	self.features.start.x = floors[r].x -- starting point at random floor location
	self.features.start.y = floors[r].y
	self.map_x = self.features.start.x - view_center_x -- map_x formula now doable
	self.map_y = self.features.start.y - view_center_y
	self.features.exits = {}
	self.features.exits[1] = {}
	self.features.exits[1].x =  floors[r].x -- create an exit to previous
	self.features.exits[1].y =  floors[r].y -- map here, under player's feet
	self.features.exits[1].dest = self.prevMap

end

function MapGen:gen_items()

end

function MapGen:gen_scourge()

end

function MapGen:gen_enemies()

end
